package BZimmerman.AndroidWars;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PointF;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;

public class BattleActivity extends Activity {
	
	private View menuView;
	Display display;
	
	public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        display = getWindowManager().getDefaultDisplay();
        menuView = new Panel(this);
    	setContentView(menuView);
    }
	
	public class Panel extends SurfaceView implements SurfaceHolder.Callback {

		private TutorialThread _thread;
		//Creates all of the graphics with the Panel resources
		public createMap map = new createMap(100);
		pZoom zoom = new pZoom(20,10);
		public int scale = display.getWidth()/(zoom.returnZoomed()+1);
		public initializeGraphics graphicsHolder = new initializeGraphics(getResources(),scale);
		public heroInfo hero =  new heroInfo(map.returnStart());
		public referenceClass ref = new referenceClass(map.map, map.size);
		PointF pLocation, pMove, pMargins, pRelease, pClickHolder;
		
		
		
		public Panel(Context context) {
			super(context);
			pLocation = new PointF(0,0);
			pClickHolder = new PointF(0,0);
			pRelease = new PointF(0,0); 
			hero.setRatio(display.getHeight(), display.getWidth());
            System.out.println("Panel Initialized");
            setFocusable(true);
            getHolder().addCallback(this);
            _thread = new TutorialThread(getHolder(), this);
			pMargins = new PointF(-(hero.getLocation().x-(zoom.returnZoomed()/2))*scale,-(hero.getLocation().y-(zoom.returnZoomed()/2)*hero.getRatio().y)*scale);
            calibrateMargins();
			
			// TODO Auto-generated constructor stub
		}
		
        @Override
        public boolean onTouchEvent(final MotionEvent event) {

        	doTask(event);
        	return true;
        }
        
        public boolean doTask(MotionEvent event){
        	
        	int action = event.getAction();
        	int actionCode = action & MotionEvent.ACTION_MASK;
        		//This is if the user presses with more than one finger
				if ((actionCode == MotionEvent.ACTION_POINTER_DOWN)) {
					zoom.toggleZoom();
	    			scale = display.getWidth()/(zoom.returnZoomed() + 1);
	    			graphicsHolder = new initializeGraphics(getResources(),scale);
            	}
				//This records where the user presses
                if ((actionCode == MotionEvent.ACTION_DOWN)) {
                	pClickHolder = new PointF(event.getX(),event.getY());
                	pLocation = new PointF(event.getX()-pMargins.x, event.getY()-pMargins.y);
                	hero.screenClicked();
                }
                //This records where the user his finger
                if ((actionCode == MotionEvent.ACTION_MOVE)) {
                	pMove = new PointF(event.getX(), event.getY());
                	
                	//System.out.println("Math.abs(pClickHolder.x-pMove.x): " + Math.abs(pClickHolder.x-pMove.x));
                	//System.out.println("Math.abs(pClickHolder.y-pMove.y): " + Math.abs(pClickHolder.y-pMove.y));
                	//System.out.println("scale: " + scale);
                	if(Math.abs(pClickHolder.x-pMove.x) > scale || Math.abs(pClickHolder.y-pMove.y) > scale){
                		//The user wants to move the screen and not click
                		hero.revertToLastMoved();
                		
                		pMargins.x = (pMove.x-pLocation.x);
                		pMargins.y = (pMove.y-pLocation.y);    	
                	
                		calibrateMargins();
                	}
                	//System.out.println("Scale:" + -map.size*scale);
                	//System.out.println("Margins:" + pMargins.x +":"+pMargins.y);
                	
                }
                //This records where the user releases
                if ((actionCode == MotionEvent.ACTION_UP)) {
                	pRelease = new PointF(pMargins.x, pMargins.y);
                	
                	//If the user didnt scroll on the board, didnt go out of bounds, or changed location in another area, center the screen on the player
                	if (!hero.screenMoved()){
                    	hero.calcLocation(pLocation, scale,map.map,map.size, graphicsHolder.returnTileSizes(0));
                    	if(hero.cursorOnHero() && hero.outOfBox(pMargins, scale, display.getWidth(), display.getHeight())){
                		pMargins.x = -(hero.getLocation().x-(zoom.returnZoomed()/2))*scale;
                		pMargins.y = -(hero.getLocation().y-(zoom.returnZoomed()/2)*hero.getRatio().y)*scale;
                		
                		calibrateMargins();
                    	}
                	}
                	//pLocation = null;
                	//pMove = null;
                	
                }
                return true;
        }
        
        public void calibrateMargins(){
        	if (pMargins.x> 0){pMargins.x = 0;}
        	if (pMargins.y> 0){pMargins.y = 0;}
        	if (pMargins.x<(-map.size*scale) + display.getWidth()){pMargins.x=(-map.size*scale) + display.getWidth();}
        	if (pMargins.y<(-map.size*scale) + display.getHeight()){pMargins.y=(-map.size*scale) + display.getHeight();}
        }

		@Override
		public void surfaceChanged(SurfaceHolder holder, int format, int width,
				int height) {
			// TODO Auto-generated method stub
			
		}

		@Override
		public void surfaceCreated(SurfaceHolder holder) {
        	if(_thread.getState() == Thread.State.TERMINATED)
            {
        		getHolder().addCallback(this);
                _thread = new TutorialThread(getHolder(), this);
            }
        		_thread.setRunning(true);
        		_thread.start();
		}

		@Override
		public void surfaceDestroyed(SurfaceHolder holder) {
			// simply copied from sample application LunarLander:
            // we have to tell thread to shut down & wait for it to finish, or else
            // it might touch the Surface after we return and explode
            boolean retry = true;
            _thread.setRunning(false);
            while (retry) {
                try {
                    _thread.join();
                    retry = false;
                    //System.out.println("All Threads Destroyed!!!");
                } catch (InterruptedException e) {
                	System.out.println(e);
                    // we will try it again and again...
                }
            }
		}
		
		public Bitmap combineImages() {
		    Bitmap bitmap;
		    bitmap = Bitmap.createBitmap(display.getWidth(), display.getHeight(), Bitmap.Config.ARGB_8888);
		    //System.out.println("Matrix: " + display.getWidth() + ":" + display.getHeight());
		    Canvas comboImage = new Canvas(bitmap); 
		    PointF marginHolder = new PointF(pMargins.x,pMargins.y);
		   
		    for(int Y=0;Y<map.size;Y++){
            	for(int X=0;X<map.size;X++){
            		//System.out.println("Matrix: " + X + ":" + Y);
            		//bitmap = graphicsHolder.returnTiles(map.returnCellValue(X, Y));
            		comboImage.drawBitmap(graphicsHolder.returnTiles(0,map.returnCellValue(X, Y)), marginHolder.x+X*scale, marginHolder.y+Y*scale, null);
            		
            		if(ref.returnCastleObject(new PointF((int)X,(int)Y)).getCastleID()!=0){
            			comboImage.drawBitmap(graphicsHolder.returnPalaces(
            					ref.returnCastleObject(new PointF((int)X,(int)Y)).getCastleID()-1,
            					ref.returnCastleObject(new PointF((int)X,(int)Y)).returnGraphicAnimation()), 
            					marginHolder.x+X*scale, marginHolder.y+Y*scale, null);
            		}
            		//Prints heroes
            		if(hero.getLocation().equals(X, Y)){
            			comboImage.drawBitmap(graphicsHolder.returnTiles(2,0), marginHolder.x+X*scale, marginHolder.y+Y*scale, null);
            		}
            		//This returns and prints the cursor
            		if(hero.getCursor().equals(X,Y) && !hero.getLocation().equals(X, Y)){
            			comboImage.drawBitmap(graphicsHolder.returnTiles(1,0), marginHolder.x+X*scale, marginHolder.y+Y*scale, null);
            		}
            	}
            }
		    
		    //Prints pathways
		    int count = 0;
	    	ArrayList<Integer> orientationDeep = new ArrayList<Integer>();
	    	for(int objects: hero.fOrientation()){
	    		orientationDeep.add(objects);
	    	}
		    for(PointF items: hero.fPath()){
		    	if(!hero.getLocation().equals(items.x, items.y) && count < orientationDeep.size()){
		    		if(hero.getCursor().equals(items.x, items.y)){
		    				//Up
		    				if(orientationDeep.get(count) == 1){
				    		comboImage.drawBitmap(graphicsHolder.rotateImage(graphicsHolder.arrow_body,270,graphicsHolder.returnTiles(1,3),false)
				    				, marginHolder.x+items.x*scale, marginHolder.y+items.y*scale, null);
				    		}
				    		//Down
				    		else if(orientationDeep.get(count) == 2){
					    		comboImage.drawBitmap(graphicsHolder.rotateImage(graphicsHolder.arrow_body,90,graphicsHolder.returnTiles(1,3),false)
					    				, marginHolder.x+items.x*scale, marginHolder.y+items.y*scale, null);
					    		}
				    		//Right
				    		else if(orientationDeep.get(count) == 4){
					    		comboImage.drawBitmap(graphicsHolder.returnTiles(1,3)
					    				, marginHolder.x+items.x*scale, marginHolder.y+items.y*scale, null);
					    		}
				    		//Left
				    		else if(orientationDeep.get(count) == 3){
				    			comboImage.drawBitmap(graphicsHolder.rotateImage(graphicsHolder.arrow_body,180,graphicsHolder.returnTiles(1,3),false)
					    				, marginHolder.x+items.x*scale, marginHolder.y+items.y*scale, null);
					    		}
		    		}
		    		//Up
		    		else if(orientationDeep.get(count) == 1 && orientationDeep.get(count+1) == 1){
		    		comboImage.drawBitmap(graphicsHolder.rotateImage(graphicsHolder.arrow_body,90,graphicsHolder.returnTiles(1,1),false)
		    				, marginHolder.x+items.x*scale, marginHolder.y+items.y*scale, null);
		    		}
		    		//Down
		    		else if(orientationDeep.get(count) == 2 && orientationDeep.get(count+1) == 2){
			    		comboImage.drawBitmap(graphicsHolder.rotateImage(graphicsHolder.arrow_body,90,graphicsHolder.returnTiles(1,1),false)
			    				, marginHolder.x+items.x*scale, marginHolder.y+items.y*scale, null);
			    		}
		    		//Left
		    		else if(orientationDeep.get(count) == 3 && orientationDeep.get(count+1) == 3){
			    		comboImage.drawBitmap(graphicsHolder.returnTiles(1,1)
			    				, marginHolder.x+items.x*scale, marginHolder.y+items.y*scale, null);
			    		}
		    		//Right
		    		else if(orientationDeep.get(count) == 4 && orientationDeep.get(count+1) == 4){
			    		comboImage.drawBitmap(graphicsHolder.returnTiles(1,1)
			    				, marginHolder.x+items.x*scale, marginHolder.y+items.y*scale, null);
			    		}
		    		
		    		//Right-Up
		    		else if((orientationDeep.get(count) == 4 && orientationDeep.get(count+1) == 1)||(orientationDeep.get(count) == 2 && orientationDeep.get(count+1) == 3)){
			    		comboImage.drawBitmap(graphicsHolder.returnTiles(1,2)
			    				, marginHolder.x+items.x*scale, marginHolder.y+items.y*scale, null);
			    		}
		    		//Up-Left
		    		else if((orientationDeep.get(count) == 1 && orientationDeep.get(count+1) == 3)||(orientationDeep.get(count) == 4 && orientationDeep.get(count+1) == 2)){
		    		comboImage.drawBitmap(graphicsHolder.rotateImage(graphicsHolder.arrow_body,270,graphicsHolder.returnTiles(1,2),false)
		    				, marginHolder.x+items.x*scale, marginHolder.y+items.y*scale, null);
		    		}
		    		//Left-Down
		    		else if((orientationDeep.get(count) == 3 && orientationDeep.get(count+1) == 2)||(orientationDeep.get(count) == 1 && orientationDeep.get(count+1) == 4)){
		    			comboImage.drawBitmap(graphicsHolder.rotateImage(graphicsHolder.arrow_body,180,graphicsHolder.returnTiles(1,2),false)
			    				, marginHolder.x+items.x*scale, marginHolder.y+items.y*scale, null);
			    		}
		    		//Down-Right
		    		else if((orientationDeep.get(count) == 2 && orientationDeep.get(count+1) == 4)||(orientationDeep.get(count) == 3 && orientationDeep.get(count+1) == 1)){
		    			comboImage.drawBitmap(graphicsHolder.rotateImage(graphicsHolder.arrow_body,90,graphicsHolder.returnTiles(1,2),false)
			    				, marginHolder.x+items.x*scale, marginHolder.y+items.y*scale, null);
			    		}
			    	count++;
		    	}
		    	//count++;
		    }

		    return bitmap; 
		  } 
		
		public void onDraw(Canvas canvas) {
			canvas.drawColor(Color.BLACK);
			Bitmap bitmap;
			Paint myPaint = new Paint();
            //for(int Y=0;Y<map.size;Y++){
            //	for(int X=0;X<map.size;X++){
            		//System.out.println("Matrix: " + X + ":" + Y);
            		//bitmap = graphicsHolder.returnTiles(map.returnCellValue(X, Y));
            		//canvas.drawBitmap(bitmap, X*scale + pMargins.x, Y*scale + pMargins.y, null);
			canvas.drawBitmap(combineImages(), 0, 0, null);
            //	}
            //}
            /*if(pLocation != null){
            	myPaint.setColor(Color.BLACK);
                myPaint.setStyle(Paint.Style.FILL); 
            	canvas.drawCircle(pLocation.x, pLocation.y, 5, myPaint);
            }
            if(pMove != null){
            	myPaint.setColor(Color.RED);
                myPaint.setStyle(Paint.Style.FILL); 
            	canvas.drawCircle(pMove.x, pMove.y, 5, myPaint);
            }*/
		}
		
	}
	
	class TutorialThread extends Thread {
        private SurfaceHolder _surfaceHolder;
        private Panel _panel;
        private boolean gameOver,endDrawn;
        private boolean _run = false;
 
        
        
        public TutorialThread(SurfaceHolder surfaceHolder, Panel panel) {
            _surfaceHolder = surfaceHolder;
            _panel = panel;
            gameOver = false;
            endDrawn = false;
        }
        public void gameDone(){
        	gameOver = true;
        }
        
        public boolean getGameStatus(){
        	return gameOver;
        }
        
        public boolean getEndStatus(){
        	return endDrawn;
        }
        
        public void setRunning(boolean run) {
            _run = run;
        }
 
        public SurfaceHolder getSurfaceHolder() {
            return _surfaceHolder;
        }
 
        @Override
        public void run() {
            Canvas c;
            while (_run) {
                c = null;
                try {
                    c = _surfaceHolder.lockCanvas(null);
                    synchronized (_surfaceHolder) {
                        _panel.onDraw(c);
                    }
                } finally {
                    // do this in a finally so that if an exception is thrown
                    // during the above, we don't leave the Surface in an
                    // inconsistent state
                    if (c != null) {
                        _surfaceHolder.unlockCanvasAndPost(c);
                    }
                }
            }
        }
    }
	
	
}
